package com.gitee.kamismile.stoneComEx.util;

import com.gitee.kamismile.stone.commmon.util.ValueUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

/**
 * 文件操作工具类
 *
 * @author Sun Xiaochen
 * @since 2008-2-1
 */

public class FileUtils {
    protected static final Logger logger = LoggerFactory.getLogger(FileUtils.class);

    // 限制实例化
    private FileUtils() {
    }

    /**
     * 从文件中读取文件
     *
     * @param path 文件路径
     * @return 文件的字符串
     * @throws IOException IO抛出异常
     */
    public static String read(String path) throws IOException {
        String[] lines = readLines(path);
        StringBuilder builder = new StringBuilder();
        for (String line : lines) {
            builder.append(line);
        }
        return builder.toString();
    }

    /**
     * 将字符串以UTF-8编码格式写入文件
     *
     * @param path    文件路径
     * @param content 写入的字符串
     * @throws IOException 文件路径错误
     */
    public static void write(String path, String content) throws IOException {
        Writer out = null;
        try {
            File file = new File(path);
            File parent = file.getParentFile();
            if (!parent.exists()) {
                parent.mkdirs();
            }
            out = new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
            out.write(content);

        } catch (Exception e) {
            logger.error("writer {} File error", path);
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }

    /**
     * 从文本文件中读取所有的行(UTF-8编码)。
     *
     * @param path 文件路径
     * @return 以数组形式存储的所有行
     * @throws java.io.IOException 读取文件有误时抛出
     */
    public static String[] readLines(String path) throws IOException {
        List<String> lines = new ArrayList<String>();
        String line = "";
        File file = new File(path);
        if (file.exists()) {
            InputStreamReader read = new InputStreamReader(new FileInputStream(file), "UTF-8");
            // BufferedReader br = new BufferedReader(read);
            // line = br.readLine();
            // while (line != null) {
            // lines.add(line);
            // line = br.readLine();
            // }
            // br.close();
            lines = readLines(read, line, false);
        }

        return lines.toArray(new String[lines.size()]);
    }

    public static List<String> readLines(InputStreamReader input, String line, boolean flag) throws IOException {
        List<String> lines = new ArrayList<String>();
        BufferedReader br = new BufferedReader(input);
        try {
            line = br.readLine();
            while (line != null) {
                if (!flag || !"".equals(line.trim())) {
                    lines.add(line);
                }
                line = br.readLine();
            }
        } finally {
            if (!Objects.isNull(br)) {
                br.close();
            }
        }

        return lines;
    }

    public static String[] readLines(InputStreamReader input) throws IOException {
        List<String> lines = new ArrayList<String>();
        String line = "";
        lines = readLines(input, line, true);
        return lines.toArray(new String[lines.size()]);
    }

    /**
     * 将字符串数组按行写入文件，如果文件已经存在将被覆盖。
     *
     * @param path  文件路径
     * @param lines 需要写入的数据
     * @throws java.io.IOException 写入文件有误时抛出
     */
    public static void writeLines(String path, String[] lines) throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter(path));
        try {
            for (String line : lines) {
                bw.write(line);
                bw.newLine();
            }
        } finally {
            IOUtils.closeQuietly(bw);
        }
    }

    /**
     * 打开文件并得到BufferedReader。
     *
     * @param file 文件
     * @return BufferedReader 如果文件不存在，返回null
     * @throws java.io.IOException 读取文件有误时抛出
     */
    public static BufferedReader getReader(File file) throws IOException {
        if (isFile(file)) {
            return new BufferedReader(new FileReader(file));
        }
        return null;
    }


    public static BufferedReader getReader(File file, String type) throws IOException {
        if (isFile(file)) {
            return new BufferedReader(new InputStreamReader(new FileInputStream(file), type));
        }
        return null;
    }

    /**
     * 打开文件，如果文件不存在，自动创建，并得到BufferedWriter。
     *
     * @param file           文件
     * @param allowOverwrite 是否运行覆盖旧文件
     * @return BufferedWriter，如果文件存在但不运行覆盖，返回null
     * @throws java.io.IOException 读取或创建新文件有误时抛出
     */
    public static BufferedWriter getWriter(File file, boolean allowOverwrite) throws IOException {
        if (checkFile(file, allowOverwrite)) {
            return new BufferedWriter(new FileWriter(file));
        }
        return null;
    }

    /**
     * 打开文件并得到InputStrea
     *
     * @param file 文件
     * @return FileInputStream，如果文件不存在，返回null
     * @throws java.io.IOException 读取文件有误时抛出
     */
    public static FileInputStream getInputStream(File file) throws IOException {
        if (isFile(file)) {
            return new FileInputStream(file);
        }
        return null;
    }

    /**
     * 打开文件，如果文件不存在，自动创建，并得到FileOutputStream。
     *
     * @param file           文件
     * @param allowOverwrite 是否运行覆盖旧文件
     * @return FileOutputStream，如果文件存在但不允许覆盖，返回null
     * @throws java.io.IOException 读取或创建新文件有误时抛出
     */
    public static FileOutputStream getOutputStream(File file, boolean allowOverwrite) throws IOException {
        if (checkFile(file, allowOverwrite)) {
            return new FileOutputStream(file);
        }
        return null;
    }

    /**
     * 关闭输入流
     *
     * @param inputStream 文件输入流
     */
    public static void close(FileInputStream inputStream) {
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException e) {
                logger.error("close FileInputStream fail", e);
            }
        }
    }

    /**
     * 关闭输出流
     *
     * @param outputStream 文件输出流
     */
    public static void close(FileOutputStream outputStream) {
        if (outputStream != null) {
            try {
                outputStream.close();
            } catch (IOException e) {
                logger.error("close FileInputStream fail", e);
            }
        }
    }

    /**
     * 关闭BufferedReader
     *
     * @param br BufferedReader
     */
    public static void close(BufferedReader br) {
        if (br != null) {
            try {
                br.close();
            } catch (IOException e) {
                logger.error("close BufferedReader fail", e);
            }
        }
    }

    /**
     * 关闭BufferedWriter
     *
     * @param bw BufferedWriter
     */
    public static void close(BufferedWriter bw) {
        if (bw != null) {
            try {
                bw.close();
            } catch (IOException e) {
                logger.error("close BufferedWriter fail", e);
            }
        }
    }

    /**
     * 如果文件存在删除文件
     *
     * @param paht 文件路径
     */
    public static void delete(String paht) {
        File file = new File(paht);
        if (file.isFile()) {
            file.delete();
        }
    }

    /**
     * 移动文件
     *
     * @param file     文件
     * @param destPath 目的文件夹
     */
    public static void moveFile(File file, String destPath) {
        if (isFile(file) && destPath != null) {
            FileInputStream in = null;
            FileOutputStream out = null;
            try {
                File destDir = new File(destPath);
                if (!destDir.exists()) {
                    destDir.mkdir();
                }

                in = new FileInputStream(file);
                out = new FileOutputStream(destDir.getPath() + File.separator + file.getName());

                // 传输字节
                byte[] buf = new byte[1024];
                int len;
                while ((len = in.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }


                file.delete();
            } catch (IOException e) {
                logger.error("can't move {} to {} ", file, destPath);
            } finally {
                IOUtils.closeQuietly(in);
                IOUtils.closeQuietly(out);
            }
        }
    }

    /**
     * 批量重命名文件夹下的文件，包括文件夹
     *
     * @param dir     目录
     * @param prefix  重命名的后文件的前缀
     * @param find    查找
     * @param replace 替换为
     * @param suffix  重命名后文件的后缀
     * @return 被重命名过的文件
     */
    public static File[] batchRename(File dir, String prefix, String find, String replace, String suffix) {
        List<File> ls = new ArrayList<File>();
        if (isDirectory(dir)) {
            File[] files = dir.listFiles();
            for (File file : files) {
                String oldName = file.getName();
                String newName = prefix + oldName.replaceAll(find, replace) + suffix;
                if (!newName.equals(oldName)) {
                    File dest = new File(file.getParent() + File.separator + newName);
                    if (file.renameTo(dest)) {
                        ls.add(dest);
                    }
                }
            }
        }
        return ls.toArray(new File[ls.size()]);
    }

    /**
     * 批量删除一个目录下的所有文件，包括文件夹
     *
     * @param dir 目录
     */
    public static void batchDelete(File dir) {
        if (isDirectory(dir)) {
            File[] files = dir.listFiles();
            for (File file : files) {
                if (file.isDirectory()) {
                    batchDelete(file);
                }
                file.delete();
            }
        }
    }

    /**
     * 批量删除一个目录下的所有文件，包括文件夹
     *
     * @param oldPath 目录
     * @param newPath 目录
     */
    public static void copyFolders(String oldPath, String newPath) {
        File dir = new File(oldPath);

        if (isDirectory(dir)) {
            File[] files = dir.listFiles();
            for (File file : files) {
                if (file.isDirectory()) {
                    logger.debug("{},{}", new Object[]{file.getPath(), newPath});
                    copyFolders(file.getPath(), newPath);
                }
                copyFile(file.getPath(), newPath);
            }
        }
    }

    /**
     * 复制单个文件
     *
     * @param oldPathFile 准备复制的文件源
     * @param newPathFile 拷贝到新绝对路径带文件名
     */
    public static void copyFile(String oldPathFile, String newPathFile) {
        InputStream inStream = null;
        FileOutputStream fs = null;
        try {
            int byteread = 0;
            File oldfile = new File(oldPathFile);
            if (oldfile.exists()) { // 文件存在时
                inStream = new FileInputStream(oldPathFile); // 读入原文件
                fs = new FileOutputStream(newPathFile);
                byte[] buffer = new byte[1024];
                while ((byteread = inStream.read(buffer)) != -1) {
                    fs.write(buffer, 0, byteread);
                }
                fs.flush();
            }
        } catch (Exception e) {
            logger.error("Copy file from {} to {} failed...", oldPathFile, newPathFile);
            logger.error(" {}", e);
        } finally {
            IOUtils.closeQuietly(fs);
            IOUtils.closeQuietly(inStream);
        }
    }


    public static void copyFile(String oldPath, String newPath, String suffix) {
        FileInputStream input = null;
        FileOutputStream output = null;
        try {
            newPath = newPath.substring(0, newPath.lastIndexOf("/") + 1);
            oldPath = oldPath.substring(0, oldPath.lastIndexOf("/") + 1);
            new File(newPath).mkdirs(); // 如果文件夹不存在 则建立新文件夹
            File a = new File(oldPath);

            String[] file = a.list();
            File temp = null;
            for (int i = 0; i < file.length; i++) {
                if (oldPath.endsWith(File.separator)) {
                    temp = new File(oldPath + file[i]);
                } else {
                    temp = new File(oldPath + File.separator + file[i]);
                }

                if (temp.isFile()
                        && (suffix.equals("/") || suffix.endsWith(".*") || temp.getName().toLowerCase()
                        .endsWith(suffix.substring(suffix.lastIndexOf("."), suffix.length()).toLowerCase()))) {
                    input = new FileInputStream(temp);
                    output = new FileOutputStream(newPath + "/" + (temp.getName()).toString());
                    byte[] b = new byte[1024];
                    int len;
                    while ((len = input.read(b)) != -1) {
                        output.write(b, 0, len);
                    }
                    output.flush();
                }
                if (temp.isDirectory() && (suffix.toLowerCase().endsWith("/")) && !temp.getName().toLowerCase().equals(".svn")) {// 如果是子文件夹并且允许移动
                    copyFolder(oldPath + "/" + file[i], newPath + "/" + file[i], true);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            logger.error("Copy folder from {} to {} failed...", oldPath, newPath);
        } finally {
            IOUtils.closeQuietly(output);
            IOUtils.closeQuietly(input);
        }

    }

    /**
     * 复制整个文件夹的内容
     *
     * @param oldPath       准备拷贝的目录
     * @param newPath       指定绝对路径的新目录
     * @param moveSubFolder 是否需要移动子文件夹
     */
    public static void copyFolder(String oldPath, String newPath, boolean moveSubFolder) {
        FileInputStream input = null;
        FileOutputStream output = null;
        try {
            new File(newPath).mkdirs(); // 如果文件夹不存在 则建立新文件夹
            File a = new File(oldPath);
            String[] file = a.list();
            File temp = null;
            for (int i = 0; i < file.length; i++) {
                if (oldPath.endsWith(File.separator)) {
                    temp = new File(oldPath + file[i]);
                } else {
                    temp = new File(oldPath + File.separator + file[i]);
                }
                if (temp.isFile()) {
                    input = new FileInputStream(temp);
                    output = new FileOutputStream(newPath + "/" + (temp.getName()).toString());
                    byte[] b = new byte[1024];
                    int len;
                    while ((len = input.read(b)) != -1) {
                        output.write(b, 0, len);
                    }
                    output.flush();
                }
                if (temp.isDirectory() && moveSubFolder && !temp.getName().toLowerCase().equals(".svn")) {// 如果是子文件夹并且允许移动
                    copyFolder(oldPath + "/" + file[i], newPath + "/" + file[i], true);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            logger.error("Copy folder from {} to {} failed...", oldPath, newPath);
        } finally {
            IOUtils.closeQuietly(output);
            IOUtils.closeQuietly(input);
        }

    }

    /**
     * 复制整个文件夹的内容(不移动子文件夹)
     *
     * @param oldPath 准备拷贝的目录
     * @param newPath 指定绝对路径的新目录
     */
    public static void copyFolder(String oldPath, String newPath) {
        copyFolder(oldPath, newPath, false);
    }

    // 检查文件是否存在，如果不存在自动创建。 如果文件存在而且不允许覆盖 -> false

    public static boolean checkFile(File file, boolean allowOverwrite) throws IOException {
        if (file != null) {
            // 检查父目录，不存在时自动创建
            File parent = file.getParentFile();
            boolean parentExist = true;
            if (parent != null && !parent.exists()) {
                parentExist = parent.mkdirs();
            }
            if (parentExist && (file.createNewFile() || (file.exists() && allowOverwrite))) {

                return true;
            }
        }
        return false;
    }

    // 是否是一个存在的文件

    public static boolean isFile(File file) {
        return file != null && file.exists() && file.isFile();
    }

    // 是否是一个存在的文件夹

    private static boolean isDirectory(File dir) {
        return dir != null && dir.exists() && dir.isDirectory();
    }


//	public static Document file2Document(String filePath) {
//		Document doc = null;
//		FileInputStream fis = null;
//		try {
//			SAXReader saxReader = new SAXReader();
//			saxReader.setEncoding("UTF-8");
//			File f = new File(filePath);
//			if (!f.exists()) {
//				return null;
//			} else {
//				fis = new FileInputStream(f);
//				doc = saxReader.read(fis);
//			}
//		} catch (Exception ex) {
//			ex.printStackTrace();
//		} finally {
//			try {
//				if (fis != null)
//					fis.close();
//			} catch (Exception e) {
//				e.printStackTrace();
//			}
//		}
//		return doc;
//	}


    public static void copyFileByNet(String requestUrl, String newPathFile) throws Exception {
        InputStream inStream = null;
        FileOutputStream fs = null;
        try {
            int byteread = 0;

            URL url = new URL(requestUrl.trim());

            inStream = url.openStream();

            checkFile(new File(newPathFile), true);
            fs = new FileOutputStream(newPathFile);
            byte[] buffer = new byte[1024];
            while ((byteread = inStream.read(buffer)) != -1) {
                fs.write(buffer, 0, byteread);
            }
            fs.flush();
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("Copy file from {} to {} failed...{}", new Object[]{requestUrl, newPathFile, e.getMessage()});
        } finally {
            IOUtils.closeQuietly(fs);
            IOUtils.closeQuietly(inStream);
        }
    }


    /**
     * 根据路径删除指定的目录或文件，无论存在与否
     *
     * @param sPath 要删除的目录或文件
     * @return 删除成功返回 true，否则返回 false。
     */
    public static boolean deleteFolder(String sPath) {
        boolean flag = false;
        File file = new File(sPath);
        // 判断目录或文件是否存在
        if (!file.exists()) { // 不存在返回 false
            return flag;
        } else {
            // 判断是否为文件
            if (file.isFile()) { // 为文件时调用删除文件方法
                return deleteFile(sPath);
            } else { // 为目录时调用删除目录方法
                return deleteDirectory(sPath);
            }
        }
    }

    /**
     * 删除单个文件
     *
     * @param sPath 被删除文件的文件名
     * @return 单个文件删除成功返回true，否则返回false
     */
    public static boolean deleteFile(String sPath) {
        boolean flag = false;
        File file = new File(sPath);
        // 路径为文件且不为空则进行删除
        if (file.isFile() && file.exists()) {
            file.delete();
            flag = true;
        }
        return flag;
    }

    /**
     * 删除目录（文件夹）以及目录下的文件
     *
     * @param sPath 被删除目录的文件路径
     * @return 目录删除成功返回true，否则返回false
     */
    public static boolean deleteDirectory(String sPath) {
        // 如果sPath不以文件分隔符结尾，自动添加文件分隔符
        if (!sPath.endsWith(File.separator)) {
            sPath = sPath + File.separator;
        }
        File dirFile = new File(sPath);
        // 如果dir对应的文件不存在，或者不是一个目录，则退出
        if (!dirFile.exists() || !dirFile.isDirectory()) {
            return false;
        }
        boolean flag = true;
        // 删除文件夹下的所有文件(包括子目录)
        File[] files = dirFile.listFiles();
        for (int i = 0; i < files.length; i++) {
            // 删除子文件
            if (files[i].isFile()) {
                flag = deleteFile(files[i].getAbsolutePath());
                if (!flag)
                    break;
            } // 删除子目录
            else {
                flag = deleteDirectory(files[i].getAbsolutePath());
                if (!flag)
                    break;
            }
        }
        if (!flag)
            return false;
        // 删除当前目录
        return dirFile.delete();
    }

    public static LinkedList<String> getNameList(String shortPath, String rootPath) {
        LinkedList<String> nameList = new LinkedList<String>();
        if (ValueUtils.isNotNull(shortPath)) {
            String filePath = rootPath + "/" + shortPath;
            File f = new File(filePath);
            File[] files = f.listFiles();
            if (files != null) {
                for (File file : files) {
                    nameList.add(file.getName());
                }
            }
        }
        return nameList;
    }


    public static File[] getFiles(String filePath) {
        File dir = new File(filePath);
        if (dir.exists()) {
            return dir.listFiles();
        } else {
            return null;
        }
    }

    public static void main(String[] args) throws Exception {
        String[] aa = FileUtils.readLines("d:\\2.csv");
        for(String a:aa){
            System.out.println("/**");
            System.out.println("*"+a.split(",")[2]);
            System.out.println("**/");
            System.out.println("private "+ StringUtils.capitalize(a.split(",")[1]) +" "+a.split(",")[0]+";");
        }
    }
}
